package cn.yotta.user.core.server.iface.common.impl;

import cn.yotta.user.core.server.iface.common.CaptchaGenerator;
import cn.yotta.user.core.server.iface.common.CaptchaStorageStrategy;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.text.MessageFormat;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @author wyaoyao
 * @date 2022/11/9 17:31
 */
@Slf4j
public class RedisCaptchaStorageStrategy implements CaptchaStorageStrategy {

    private final StringRedisTemplate stringRedisTemplate;

    private static final String CAPTCHA_CACHE_TEMPLATE = "yotta_user_captcha_token:token:{0}";

    private final ObjectMapper objectMapper;

    public RedisCaptchaStorageStrategy(StringRedisTemplate stringRedisTemplate) {
        this.stringRedisTemplate = stringRedisTemplate;
        this.objectMapper = new ObjectMapper();
    }

    @Override
    public String save(CaptchaGenerator.Captcha captcha) {
        final String token = UUID.randomUUID().toString();
        String cacheKey = this.getCacheKey(token);

        try {
            String valueAsString = objectMapper.writeValueAsString(captcha);
            stringRedisTemplate.opsForValue().set(cacheKey, valueAsString, captcha.getExpireTime(), TimeUnit.SECONDS);
        } catch (JsonProcessingException e) {
            // ignore
            log.error("save captcha to redis error; ", e);
        }
        return token;
    }


    @Override
    public CaptchaGenerator.Captcha get(String token) {
        String cacheKey = this.getCacheKey(token);
        final String value = stringRedisTemplate.opsForValue().get(cacheKey);
        CaptchaGenerator.Captcha result = null;
        if (StringUtils.isNotEmpty(value)) {
            try {
                result = objectMapper.readValue(value, CaptchaGenerator.Captcha.class);
            } catch (JsonProcessingException e) {
                // ignore
                log.error("get captcha from redis error; ", e);
            }
        }
        return result;
    }

    private String getCacheKey(String token) {
        return MessageFormat.format(CAPTCHA_CACHE_TEMPLATE, token);
    }
}
